package org.mysterylab.utopiaframework.web.interceptor;

import java.util.Arrays;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.mysterylab.utopiaframework.util.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
 * 登录的拦截方法. 除了已登录之外, 有些应用还必须保证当前用户已通过邮箱认证才允许进行下一步操作,
 * 当然你也可以将邮箱认证的部分去除.<br>
 * 需要在 springmvc-servlet.xml 中配置如下:
 * <pre>
 * {@code
 *  <!--被保护的 URL 请求-->
 *  <mvc:interceptors>
 *      <!-- 需要登录才能完成下列操作 -->
 *      <bean class="org.mysterylab.utopiaframework.web.interceptor.SigninInterceptor">
 *          <property name="limitUrls">
 *              <list>
 *                  <value>/member/</value>
 *              </list>
 *          </property>
 *          <property name="loginView" value="/login" />
 *          <property name="emailConfirmView" value="/emailconfirm" />
 *      </bean>
 *  </mvc:interceptors>
 * }
 * </pre>
 * 
 * @author zhouych
 */
public class SigninInterceptor extends HandlerInterceptorAdapter {
	
	private static Logger logger = LoggerFactory.getLogger(SigninInterceptor.class);

	/**
	 * 被限制访问的资源url
	 */
	private List<String> limitUrls;
	
	/**
	 * 登录页面
	 */
	private String loginView;
	
	/**
	 * 邮箱认证页面
	 */
	private String emailConfirmView;
	
	public void setLimitUrls(String[] limitUrls) {
		this.limitUrls = Arrays.asList(limitUrls);
	}

	public void setLoginView(String loginView) {
		this.loginView = loginView;
	}

	public void setEmailConfirmView(String emailConfirmView) {
		this.emailConfirmView = emailConfirmView;
	}

	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		
		// 如果用户未登录
		if (request.getSession().getAttribute(Constants.CURRENT_USER) == null) {
			for (String url : limitUrls) {
				if (request.getRequestURI().indexOf(url) != -1) {
					/*
					 * 如果请求的url中包含了当前受限的url，则转到登录页面，在这之
					 * 前需要先将当前页面url存储下来，待会登录完毕之后返回该页面。
					 * 但是可能由于某些REST的缘故（比如请求方法为POST，而请求地址
					 * 为http://~/customers/favorite/{id}，这个是给用户添加收藏的，
					 * 但是经过该方法之后会使用GET方法去请求同样的url地址，这个时候
					 * 就有可能不知道该返回哪个地址，比如购物车页面或单个图书介绍页
					 * 面等）。我们需要使用JS来获取浏览器中的地址，采用这个地址优先
					 */
					String preView = request.getParameter("preView");
					if (!StringUtils.isBlank(preView)) {
						// 如果存在该地址，说明需要返回浏览器的地址
						logger.debug("previous view before login is {}", preView);
						request.getSession().setAttribute("preview", preView);
					} else {
//						System.out.println(HttpUtil.getRequestURL(request));
//						request.getSession().setAttribute(Constants.PRE_VIEW,
//			        			HttpUtil.getRequestURL(request));
					}
					response.sendRedirect(request.getContextPath() + loginView);
					return false;
				}
			}
		} else if (false) {
			// 如果邮箱未认证，这里默认为已认证，return false
			response.sendRedirect(request.getContextPath() + emailConfirmView);
			return false;
		}
		return true;
	}
}
